package com.axinfu.util.config;

import com.axinfu.util.config.callback.ApplyCallBack;
import com.axinfu.util.config.callback.CustomAction;
import com.axinfu.util.config.http.BtgSetServlet;
import com.axinfu.util.config.util.BtgSetHelper;

import javax.sql.DataSource;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * BtgSetPlugin
 *
 * @author zjn
 * @since 2022/3/24
 */
@SuppressWarnings("unused")
public class BtgSetPlugin {

    private static final String JDBC_MYSQL = "jdbc:mysql";
    private static final String JDBC_ORACLE = "jdbc:oracle:thin";

    private String url;
    private String username;
    private String password;
    private String driverClass = null;
    private DataSource dataSource = null;
    private Dialect dialect;
    private String setTemplet;

    private int sessionTimeOut = 30;
    private boolean isRefreshSession = false;

    protected List<ApplyCallBack> applyCallBackList = new ArrayList<>();

    public List<CustomAction> excuteCallBackList = new ArrayList<>();

    private final Map<String, String> tabMap = new HashMap<>();

    private volatile static BtgSetPlugin btgSetPlugin;

    public BtgSetPlugin() {
    }

    public static BtgSetPlugin getBtgSetPlugin() {
        return btgSetPlugin;
    }

    public static BtgSetPlugin initBtgSetPlugin(DataSource dataSource, Dialect dialect) {
        if (btgSetPlugin == null) {
            synchronized (BtgSetPlugin.class) {
                if (btgSetPlugin == null) {
                    btgSetPlugin = new BtgSetPlugin(dataSource, dialect);
                }
            }
        }
        return btgSetPlugin;
    }

    public static BtgSetPlugin initBtgSetPlugin(String url, String username, String password) {
        if (btgSetPlugin == null) {
            synchronized (BtgSetPlugin.class) {
                if (btgSetPlugin == null) {
                    btgSetPlugin = new BtgSetPlugin(url, username, password);
                }
            }
        }
        return btgSetPlugin;
    }

    public static BtgSetPlugin initBtgSetPlugin(String url, String username, String password, String driverClass) {
        if (btgSetPlugin == null) {
            synchronized (BtgSetPlugin.class) {
                if (btgSetPlugin == null) {
                    btgSetPlugin = new BtgSetPlugin(url, username, password, driverClass);
                }
            }
        }
        return btgSetPlugin;
    }

    public static BtgSetPlugin initBtgSetPlugin(String url, String username, String password, Dialect dialect) {
        if (btgSetPlugin == null) {
            synchronized (BtgSetPlugin.class) {
                if (btgSetPlugin == null) {
                    btgSetPlugin = new BtgSetPlugin(url, username, password, dialect);
                }
            }
        }
        return btgSetPlugin;
    }

    public static BtgSetPlugin initBtgSetPlugin(String url, String username, String password, String driverClass,
                                                Dialect dialect) {
        if (btgSetPlugin == null) {
            synchronized (BtgSetPlugin.class) {
                if (btgSetPlugin == null) {
                    btgSetPlugin = new BtgSetPlugin(url, username, password, driverClass, dialect);
                }
            }
        }
        return btgSetPlugin;
    }

    private BtgSetPlugin(String url, String username, String password) {
        this.url = url;
        this.username = username;
        this.password = password;
        initDialect(url);
    }

    private BtgSetPlugin(String url, String username, String password, String driverClass) {
        this.url = url;
        this.username = username;
        this.password = password;
        this.driverClass = driverClass;
        initDialect(url);
    }

    private BtgSetPlugin(DataSource dataSource, Dialect dialect) {
        this.dataSource = dataSource;
        this.dialect = dialect;
    }

    private BtgSetPlugin(String url, String username, String password, Dialect dialect) {
        this.url = url;
        this.username = username;
        this.password = password;
        this.dialect = dialect;
    }

    private BtgSetPlugin(String url, String username, String password, String driverClass, Dialect dialect) {
        this.url = url;
        this.username = username;
        this.password = password;
        this.driverClass = driverClass;
        this.dialect = dialect;
    }

    private void initDialect(String url) {
        if (url != null && !"".equals(url)) {
            if (url.toLowerCase().startsWith(JDBC_MYSQL)) {
                this.dialect = Dialect.MYSQL;
                return;
            }
            if (url.toLowerCase().startsWith(JDBC_ORACLE)) {
                this.dialect = Dialect.ORACLE;
            }
        }
    }

    public Dialect getDialect() {
        return this.dialect;
    }

    public BtgSetPlugin setTemplet(String path) {
        this.setTemplet = path;
        return btgSetPlugin;
    }

    public Map<String, String> getTabMap() {
        return this.tabMap;
    }

    public String getTemplet() {
        return this.setTemplet;
    }

    public BtgSetPlugin setApplyCallBack(ApplyCallBack callBack) {
        if (callBack != null) {
            this.applyCallBackList.add(callBack);
        }
        return btgSetPlugin;
    }


    public BtgSetPlugin setExcuteCallBack(CustomAction customAction) {
        if (customAction != null) {
            this.excuteCallBackList.add(customAction);
        }
        return btgSetPlugin;
    }

    public int getSessionTimeOut() {
        return this.sessionTimeOut;
    }

    public BtgSetPlugin setSessionTimeOut(int sessionTimeOut) {
        this.sessionTimeOut = sessionTimeOut;
        return btgSetPlugin;
    }

    public boolean getIsRefreshSession() {
        return this.isRefreshSession;
    }

    public BtgSetPlugin setIsRefreshSession(boolean isRefreshSession) {
        this.isRefreshSession = isRefreshSession;
        return btgSetPlugin;
    }

    public Connection getConnection() {
        try {
            if (dataSource != null) {
                return dataSource.getConnection();
            } else {
                if (driverClass == null) {
                    switch (dialect) {
                        case MYSQL:
                            driverClass = "com.mysql.jdbc.Driver";
                            break;
                        case ORACLE:
                            driverClass = "oracle.jdbc.driver.OracleDriver";
                            break;
                        default:
                            break;
                    }
                }
                Class.forName(driverClass);
                return DriverManager.getConnection(url, username, password);
            }
        } catch (SQLException | ClassNotFoundException e) {
            e.printStackTrace();
        }
        return null;
    }

    public void init() {
        init(null);
    }

    public void init(String tabSuffix) {
        if (tabSuffix == null) {
            tabSuffix = "";
        }
        List<String> list = BtgSetHelper.getInstance().getTabName(dialect);
        for (String str : list) {
            tabMap.put(str, tabSuffix + str);
        }

        Connection conn = null;
        Statement statement = null;
        ResultSet rs;
        try {
            conn = BtgSetPlugin.getBtgSetPlugin().getConnection();
            statement = conn.createStatement();
            String sql = "select count(1)row_no from " + tabMap.get("btg_set_cfg_module");
            rs = statement.executeQuery(sql);
            boolean con = false;
            while (rs.next()) {
                if (rs.getInt("row_no") > 0) {
                    con = true;
                }
            }
            //写入默认配置
            if (!con) {
                BtgSetHelper.getInstance().writeDefaultSet();
            }
        } catch (SQLException e) {
            //构造参数环境
            BtgSetHelper.getInstance().resetDataBaseEnv();
            //写入默认配置
            BtgSetHelper.getInstance().writeDefaultSet();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            BtgSetHelper.getInstance().initValue();
            try {
                if (statement != null) {
                    statement.close();
                }
                if (conn != null) {
                    conn.close();
                }
            } catch (SQLException e) {
                e.printStackTrace();
            }
            BtgSetServlet.initBtgSetPlugin();
        }
    }


}
